package cn.xd.base.application.service.command.impl;

import cn.hutool.core.collection.CollUtil;
import cn.xd.base.application.service.command.AdminRoleAppService;
import cn.xd.base.basic.type.AdminOrgRoleId;
import cn.xd.base.basic.type.AdminRoleId;
import cn.xd.base.domain.bean.command.AddAdminRoleCommand;
import cn.xd.base.domain.bean.command.UpdateAdminRoleCommand;
import cn.xd.base.domain.bean.command.common.ChangeStatusCommand;
import cn.xd.base.domain.entity.AdminOrgRole;
import cn.xd.base.domain.entity.AdminRole;
import cn.xd.base.domain.repository.AdminRoleRepository;
import cn.xd.base.persistence.dos.AdminOrgRoleConverter;
import cn.xd.base.persistence.dos.AdminOrgRoleDO;
import cn.xd.base.persistence.dos.AdminUserOrgRoleDO;
import cn.xd.base.persistence.mps.AdminOrgRoleMpService;
import cn.xd.base.persistence.mps.AdminUserOrgRoleMpService;
import cn.xd.common.exception.BizException;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class AdminRoleAppServiceImpl implements AdminRoleAppService {
    @Resource
    private AdminRoleRepository adminRoleRepository;
    @Resource
    private AdminOrgRoleMpService adminOrgRoleMpService;
    @Resource
    private AdminUserOrgRoleMpService adminUserOrgRoleMpService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAdminRole(AddAdminRoleCommand command, Long userId) {
        AdminRole add = AdminRole.add(command, userId);
        adminRoleRepository.save(add);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdminRole(UpdateAdminRoleCommand command, List<Long> orgIds, Long userId) {
        AdminRole adminRole = adminRoleRepository.find(AdminRoleId.of(command.getId())).isEmptyThrow("当前角色不存在");
        for (AdminOrgRole orgRole : adminRole.getOrgs()) {
            if (!command.getOrgIds().contains(orgRole.getOrgId().getValue())) {
                adminUserOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminUserOrgRoleDO.class).in(AdminUserOrgRoleDO::getOrgRoleId, orgRole.getId().getValue()));
            }
        }
        List<AdminOrgRole> completeAdminOrgRole = getCompleteAdminOrgRole(command.getId(), orgIds);
        List<AdminOrgRole> adminOrgRoles = getAdminOrgRole(command.getId(), orgIds);
        adminRole.update(command, adminOrgRoles, completeAdminOrgRole, userId);
        adminRoleRepository.save(adminRole);
    }

    /**
     * 补全 查询所有非当前机构的关系
     * 因为前端只能查询到当前机构及其下属机构
     *
     * @param roleId
     * @param orgIds
     * @return
     */
    private List<AdminOrgRole> getCompleteAdminOrgRole(Long roleId, List<Long> orgIds) {
        List<AdminOrgRoleDO> list = adminOrgRoleMpService.lambdaQuery().notIn(AdminOrgRoleDO::getOrgId, orgIds).eq(AdminOrgRoleDO::getRoleId, roleId).list();
        return AdminOrgRoleConverter.INSTANCE.fromData(list);
    }

    /**
     * 非补全 查询所有当前机构的关系(当前及其下属机构)
     *
     * @param roleId
     * @param orgIds
     * @return
     */
    private List<AdminOrgRole> getAdminOrgRole(Long roleId, List<Long> orgIds) {
        List<AdminOrgRoleDO> list = adminOrgRoleMpService.lambdaQuery().in(AdminOrgRoleDO::getOrgId, orgIds).eq(AdminOrgRoleDO::getRoleId, roleId).list();
        return AdminOrgRoleConverter.INSTANCE.fromData(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeAdminRoleStatus(ChangeStatusCommand command, Long userId) {
        AdminRole adminRole = adminRoleRepository.find(AdminRoleId.of(command.getId())).isEmptyThrow("当前角色不存在");
        adminRole.changeStatus(command, userId);
        adminRoleRepository.save(adminRole);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, List<Long> orgIds) {
        if (id == 0L) {
            throw new BizException("超级管理员角色不能删除");
        }
        AdminRole adminRole = adminRoleRepository.find(AdminRoleId.of(id)).isEmptyThrow("当前角色不存在");
        List<Long> completeAdminOrgRole = getCompleteAdminOrgRole(id, orgIds).stream().map(AdminOrgRole::getId).map(AdminOrgRoleId::getValue).toList();
        List<Long> adminOrgRole = getAdminOrgRole(id, orgIds).stream().map(AdminOrgRole::getId).map(AdminOrgRoleId::getValue).toList();
        if (CollUtil.isEmpty(completeAdminOrgRole)) {
            adminUserOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminUserOrgRoleDO.class).in(AdminUserOrgRoleDO::getOrgRoleId, adminOrgRole));
            adminOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminOrgRoleDO.class).eq(AdminOrgRoleDO::getRoleId, id));
            adminRoleRepository.remove(adminRole);
        } else {
            adminUserOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminUserOrgRoleDO.class).in(AdminUserOrgRoleDO::getOrgRoleId, adminOrgRole));
            adminOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminOrgRoleDO.class).eq(AdminOrgRoleDO::getRoleId, id)
                    .in(AdminOrgRoleDO::getId, adminOrgRole)
            );
        }
    }
}
